/////////////////////////////////////////////////
/////////////////////////////////////////////////
//
// Basic JavaScript File and Directory IO module
// By: MonkeeSage, v0.1
//
/////////////////////////////////////////////////
/////////////////////////////////////////////////


if (typeof(JSIO) != 'boolean') {

    var JSIO = true;

    /////////////////////////////////////////////////
    // Basic file IO object based on Mozilla source
    // code post at forums.mozillazine.org
    /////////////////////////////////////////////////

    // Example use:
    // var         fileIn = FileIO.open('/test.txt');
    // if (fileIn.exists()) {
    //   var fileOut = FileIO.open('/copy of test.txt');
    //   var str = FileIO.read(fileIn);
    //   var rv = FileIO.write(fileOut, str);
    //   alert('File write: ' + rv);
    //   rv = FileIO.write(fileOut, str, 'a');
    //   alert('File append: ' + rv);
    //   rv = FileIO.unlink(fileOut);
    //   alert('File unlink: ' + rv);
    // }

    var        FileIO = {

        localfileCID  : '@mozilla.org/file/local;1',
        localfileIID  : Components.interfaces.nsILocalFile,

        finstreamCID  : '@mozilla.org/network/file-input-stream;1',
        finstreamIID  : Components.interfaces.nsIFileInputStream,

        foutstreamCID : '@mozilla.org/network/file-output-stream;1',
        foutstreamIID : Components.interfaces.nsIFileOutputStream,

        sinstreamCID  : '@mozilla.org/scriptableinputstream;1',
        sinstreamIID  : Components.interfaces.nsIScriptableInputStream,

        suniconvCID   : '@mozilla.org/intl/scriptableunicodeconverter',
        suniconvIID   : Components.interfaces.nsIScriptableUnicodeConverter,

        open   : function(path) {
            try {
                var    file = Components.classes[this.localfileCID].createInstance(this.localfileIID);

                file.initWithPath(path);

                return file;
            } catch(e) {
                return false;
            }
        },

        read   : function(file, charset) {
            try {
                var    data     = new String();
                var    fiStream = Components.classes[this.finstreamCID].createInstance(this.finstreamIID);
                var    siStream = Components.classes[this.sinstreamCID].createInstance(this.sinstreamIID);

                fiStream.init(file, 1, 0, false);
                siStream.init(fiStream);
                data += siStream.read(-1);
                siStream.close();
                fiStream.close();

                if (charset) {
                    data = this.toUnicode(charset, data);
                }

                return data;
            }
            catch(e) {
                return false;
            }
        },

        write  : function(file, data, mode, charset) {
            try {
                var foStream = Components.classes[this.foutstreamCID] .createInstance(this.foutstreamIID);

                if (charset) {
                    data = this.fromUnicode(charset, data);
                }

                var    flags = 0x02 | 0x08 | 0x20; // wronly | create | truncate

                if (mode == 'a') {
                    flags = 0x02 | 0x10; // wronly | append
                }

                foStream.init(file, flags, 0664, 0);
                foStream.write(data, data.length);
                // foStream.flush();
                foStream.close();

                return true;
            }
            catch(e) {
                return false;
            }
        },

        create : function(file) {
            try {
                file.create(0x00, 0664);
                return true;
            }
            catch(e) {
                return false;
            }
        },

        unlink : function(file) {
            try {
                file.remove(false);
                return true;
            }
            catch(e) {
                return false;
            }
        },

        path   : function(file) {
            try {
                return 'file:///' + file.path.replace(/\\/g, '\/')
                    .replace(/^\s*\/?/, '').replace(/\ /g, '%20');
            }
            catch(e) {
                return false;
            }
        },

        toUnicode   : function(charset, data) {
            try{
                var     uniConv = Components.classes[this.suniconvCID].createInstance(this.suniconvIID);

                uniConv.charset = charset;
                data = uniConv.ConvertToUnicode(data);
            }
            catch(e) {
                // foobar!
            }
            return data;
        },

        fromUnicode : function(charset, data) {
            try {
                var uniConv = Components.classes[this.suniconvCID].createInstance(this.suniconvIID);

                uniConv.charset = charset;
                data = uniConv.ConvertFromUnicode(data);
                // data += uniConv.Finish();
            }
            catch(e) {
                // foobar!
            }
            return data;
        }

    }


    /////////////////////////////////////////////////
    // Basic Directory IO object based on JSLib
    // source code found at jslib.mozdev.org
    /////////////////////////////////////////////////

    // Example use:
    // var dir = DirIO.open('/test');
    // if (dir.exists()) {
    //   alert(DirIO.path(dir));
    //   var arr = DirIO.read(dir, true), i;
    //   if (arr) {
    //     for (i = 0; i < arr.length; ++i) {
    //       alert(arr[i].path);
    //     }
    //   }
    // }
    // else {
    //   var rv = DirIO.create(dir);
    //   alert('Directory create: ' + rv);
    // }

    // ---------------------------------------------
    // ----------------- Nota Bene -----------------
    // ---------------------------------------------
    // Some possible types for get are:
    //   'ProfD'        = profile
    //   'DefProfRt'      = user (e.g., /root/.mozilla)
    //   'UChrm'        = %profile%/chrome
    //   'DefRt'        = installation
    //   'PrfDef'        = %installation%/defaults/pref
    //   'ProfDefNoLoc'    = %installation%/defaults/profile
    //   'APlugns'      = %installation%/plugins
    //   'AChrom'        = %installation%/chrome
    //   'ComsD'        = %installation%/components
    //   'CurProcD'      = installation (usually)
    //   'Home'        = OS root (e.g., /root)
    //   'TmpD'        = OS tmp (e.g., /tmp)

    var        DirIO = {

        sep        : '/',

        dirservCID : '@mozilla.org/file/directory_service;1',

        propsIID   : Components.interfaces.nsIProperties,

        fileIID    : Components.interfaces.nsIFile,

        get    : function(type) {
            try {
                var    dir = Components.
                          classes[this.dirservCID].createInstance(this.propsIID).get(type, this.fileIID);

                return dir;
            }
            catch(e) {
                return false;
            }
        },

        open   : function(path) {
            return FileIO.open(path);
        },

        create : function(dir) {
            try {
                dir.create(0x01, 0664);
                return true;
            }
            catch(e) {
                return false;
            }
        },

        read   : function(dir, recursive) {

            var    list = new Array();

            try {
                if (dir.isDirectory()) {
                    if (recursive == null) {
                        recursive = false;
                    }

                    var     files = dir.directoryEntries;

                    list = this._read(files, recursive);
                }
            }
            catch(e) {
                // foobar!
            }
            return list;
        },

        _read  : function(dirEntry, recursive) {

            var    list = new Array();

            try {
                while (dirEntry.hasMoreElements()) {
                    list.push(dirEntry.getNext().QueryInterface(FileIO.localfileIID));
                }

                if (recursive) {

                    var     list2 = new Array();

                    for (var i = 0; i < list.length; ++i) {
                        if (list[i].isDirectory()) {
                            files = list[i].directoryEntries;
                            list2 = this._read(files, recursive);
                        }
                    }

                    for (i = 0; i < list2.length; ++i) {
                        list.push(list2[i]);
                    }
                }
            }
            catch(e) {
                // foobar!
            }
            return list;
        },

        unlink : function(dir, recursive) {
            try {
                if (recursive == null) {
                    recursive = false;
                }

                dir.remove(recursive);
                return true;
            }
            catch(e) {
                return false;
            }
        },

        path   : function (dir) {
            return FileIO.path(dir);
        },

        split  : function(str, join) {

            var    arr = str.split(/\/|\\/), i;

            str = new String();

            for (i = 0; i < arr.length; ++i) {
                str += arr[i] + ((i != arr.length - 1) ? join : '');
            }

            return str;
        },

        join   : function(str, split) {

            var    arr = str.split(split), i;

            str = new String();

            for (i = 0; i < arr.length; ++i) {
                str += arr[i] + ((i != arr.length - 1) ? this.sep : '');
            }

            return str;
        }

    }

    if (navigator.platform.toLowerCase().indexOf('win') > -1) {
        DirIO.sep = '\\';
    }

}
